package com.winchain.chainbill.bill.biz.discount.cmd;

import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.framework.command.CallbackContext;
import com.shell.framework.command.CommandContext;
import com.shell.framework.command.ICallback;
import com.shell.framework.command.ICommand;
import com.winchain.chainbill.basic.context.TimeoutOperation;
import com.winchain.chainbill.bill.base.po.CbDct;
import com.winchain.chainbill.bill.base.po.CbOpt;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.service.CbDctService;
import com.winchain.chainbill.bill.biz.Bill;
import com.winchain.chainbill.bill.biz.BillEvent;
import com.winchain.chainbill.bill.biz.discount.rx.BillDctRecoverCpnSubscriber;
import com.winchain.chainbill.bill.biz.discount.rx.BillDctSubscriber;
import com.winchain.chainbill.bill.biz.send.rx.BillMoveSubscriber;
import com.winchain.chainbill.bill.biz.send.rx.BillOptSubscriber;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import rx.Observable;

@Component
public class BillDctCmd
  implements ICommand<Bill<CbDct>>, ICallback<Bill<CbDct>, AcctTxRec>
{
  @Autowired
  private CbDctService cbDctService;
  @Autowired
  private BillOptSubscriber billOptSubscriber;
  @Autowired
  private BillMoveSubscriber billMoveSubscriber;
  @Autowired
  private BillDctSubscriber billDctSubscriber;
  @Autowired
  private BillDctRecoverCpnSubscriber billDctRecoverCpnSubscriber;
  
  public boolean execute(CommandContext<Bill<CbDct>> context)
    throws Exception
  {
    CbRec record = ((Bill)context.getSource()).getRec();
    CbDct cbDct = (CbDct)((Bill)context.getSource()).getSource();
    
    Object timeOut = context.getValue("Timeout");
    CbOpt cbOpt;
    if ((timeOut != null) && (((Boolean)timeOut).booleanValue()))
    {
      Object children = context.getValue("children");
      if (children != null)
      {
        List<Bill<CbDct>> bills = (List)children;
        if (bills.size() == 0)
        {
          cbDct.setDctState("0");
          cbDct.setPmtState("1");
        }
        else
        {
          TimeoutOperation timeoutOperation = (TimeoutOperation)context.getValue("TimeoutOperation");
          cbOpt = new CbOpt();
          cbOpt.setOptCode(timeoutOperation.getOptCode());
          cbOpt.setRemark(timeoutOperation.getRemark());
          for (Bill<CbDct> bill : bills)
          {
            ((CbDct)bill.getSource()).setDctState("0");
            ((CbDct)bill.getSource()).setPmtState("1");
            
            BillEvent<CbDct> event = new BillEvent(bill);
            
            event.setOperation(cbOpt);
            
            Observable<BillEvent<CbDct>> observers = Observable.just(event);
            
            observers.subscribe(this.billOptSubscriber);
            observers.subscribe(this.billMoveSubscriber);
            observers.subscribe(this.billDctRecoverCpnSubscriber);
            observers.subscribe(this.billDctSubscriber);
          }
        }
      }
    }
    if ((cbDct != null) && (cbDct.getDctId() != null))
    {
      cbDct.setOptSeq(record.getOptSeq());
      this.cbDctService.saveOrUpdate(cbDct);
    }
    return false;
  }
  
  public boolean callback(CallbackContext<Bill<CbDct>, AcctTxRec> context)
    throws Exception
  {
    execute(context);
    return false;
  }
}
